﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tomahawk.Runtime;
using Tomahawk.Runtime.Logic;
using Microsoft.Xna.Framework;
using Tomahawk.Runtime.Components;
using Tomahawk.Runtime.Rendering.Materials;
using Tomahawk.Runtime.Rendering;
using Tomahawk.Runtime.Rendering.Objects;
using Tomahawk.Runtime.Rendering.Interfaces;

namespace Initialization.GameStates
{
    public class LightActor : XActor
    {
        float time = 0.0f;

        public LightActor()
        {
            UpdateRequired = true;
        }

        public void ConfigureLight(ref SASRenderEnvironment.LightDefinition light, Vector4 position, Vector4 ambient, Vector4 diffuse, Vector4 specular)
        {
            light.position = position;
            light.diffuse = diffuse;
            light.specular = specular;
            light.ambient = ambient;
        }

        protected override void OnUpdate(float elapsedTime)
        {
            time += elapsedTime;
            //Engine.Instance.RenderManager.Environment.light0.position.X = 200.0f * (float)Math.Sin(time);
            base.OnUpdate(elapsedTime);
        }
    }

    public class SpriteActor : XActor
    {
        protected Vector4 offset = Vector4.Zero;

        public SpriteActor()
        {
            UpdateRequired = true;
        }

        public void OnRenderMaterial(IRenderable source, SASMaterial material)
        {
            material.Effect.Parameters["CurrentSprite"].SetVectorValue(ref offset);
        }

        protected override void OnPostBeginPlay()
        {
            XMaterialPlaneComponent plane = GetComponent<XMaterialPlaneComponent>();
            if (plane != null)
            {
                plane.QuadModel.OnPrepareMaterial += new RenderMaterialDelegate(OnRenderMaterial);
            }
        }

        protected override void OnUpdate(float elapsedTime)
        {
            offset.X += elapsedTime;
            
            base.OnUpdate(elapsedTime);
        }
    }

    public class TeapotActor : XActor
    {
        public TeapotActor()
        {
            UpdateRequired = true;
        }

        protected override void OnUpdate(float elapsedTime)
        {
            Quaternion delta = Quaternion.CreateFromAxisAngle(Vector3.Forward, elapsedTime);
            this.SetRotation(this.SceneComponent.SceneNode.Rotation * delta);
            base.OnUpdate(elapsedTime);
        }
    }

    class BasicGameState : GameState
    {
        SASEffect standardEffect = null;
        public SASEffect StandardEffect { get { return standardEffect; } }

        protected override void OnLoad()
        {
            SASMaterial material = Engine.Instance.MaterialManager.Load<SASEffect>(@"Tomahawk.Content\Materials\generics@standard_Material", this.ContentManager);
            standardEffect = material.Effect;

            LightActor light0 = (LightActor)XWorld.Instance.CreateObject(typeof(LightActor));
            light0.ConfigureLight(
                ref Engine.Instance.RenderManager.Environment.light0,
                new Vector4(-50, -50, 0, 1), 
                new Vector4(0.1f, 0.1f, 0.1f, 1.0f),
                new Vector4(1.0f, 1.0f, 1.0f, 1.0f),
                new Vector4(1.0f, 1.0f, 0.0f, 1.0f));

            int size = 20;
            float scale = 0.2f;

            Vector2 rangeH = new Vector2(-200, 0);
            Vector2 rangeV = new Vector2(-100, 100);
            Vector3 position = new Vector3(0, rangeV.X, rangeH.X);

            
            float stepZ = rangeH.Length() / (size - 1);
            float stepY = rangeV.Length() / (size - 1);

            for (int i = 0; i < size; ++i)
            {
                for (int j = 0; j < size; ++j)
                {
                    TeapotActor teapot = (TeapotActor)XWorld.Instance.CreateObject(typeof(TeapotActor), "", @"Examples.Shaders.Content\teapot0actor.xml");
                    teapot.SetLocation(position);
                    teapot.SetScale(new Vector3(scale));
                    position.Z += stepZ;
                }

                position.Y += stepY;
                position.Z = rangeH.X;
            }
            
            TeapotActor bigTeapot = (TeapotActor)XWorld.Instance.CreateObject(typeof(TeapotActor), "", @"Examples.Shaders.Content\teapot0actor.xml");
            bigTeapot.SetLocation(new Vector3(0, 0, 50));


            SpriteActor sprites = (SpriteActor)XWorld.Instance.CreateObject(typeof(SpriteActor), "", @"Examples.Shaders.Content\spriteactor.xml");
            sprites.SetLocation(new Vector3(0, -50, 50));

            Engine.Instance.ResourceManager.LoadPendantResources(this.ContentManager);
        }

        protected override void OnUnload()
        {
        }

        protected override void OnInitialize()
        {
            Engine.Instance.CameraManager.SetActiveCamera(FreeCamComponent.label);
            Tomahawk.Runtime.Rendering.Camera camera = Engine.Instance.CameraManager.ActiveCamera;
            camera.LookAt(
                new Vector3(-400, 0, 0),
                new Vector3(0, 0, 0),
                Vector3.UnitY);
        }

        protected override void OnDestroy()
        {
        }
    }
}
